package com.chixing.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chixing.mapper.TemplateKillMapper;
import com.chixing.pojo.TemplateKill;
import com.chixing.service.ITemplateKillService;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xyh
 * @since 2022-11-04
 */
@Service
public class TemplateKillServiceImpl extends ServiceImpl<TemplateKillMapper, TemplateKill> implements ITemplateKillService {

    @Autowired
    TemplateKillMapper templateKillMapper;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Override
    public List<TemplateKill> getAllTemplate() {
        List<TemplateKill> templateKillList = templateKillMapper.selectList(null);
        //将秒杀模板加载到redis
        for (TemplateKill templateKill : templateKillList ) {
            String key = "templateKill_"+templateKill.getTemplateKillId();
            redisTemplate.opsForValue().set(key,templateKill,24, TimeUnit.HOURS);
        }
        return templateKillList;
    }

    //分布式锁，redis减库存
    @Override
    public TemplateKill deleteInventory(Integer TemplateId) {
        UUID uuids = UUID.randomUUID();
        String uuid = uuids.toString().replace("-","");
        String key = "templateKill_"+TemplateId;
        TemplateKill templateKill = null;
        //上锁
        Boolean result = redisTemplate.opsForValue().setIfAbsent("key", uuid, 10, TimeUnit.SECONDS);
        if(result){
            //加锁成功，获得缓存中的简历模板
            templateKill = (TemplateKill) redisTemplate.opsForValue().get("templateKill_"+TemplateId);
            //判断该简历模板是否存在，库存是否充足
            if(templateKill==null){
                return null;
            }
            if(templateKill.getTemplateKillInventory() == 0){
                return null;
            }
            //减库存
            templateKill.setTemplateKillInventory(templateKill.getTemplateKillInventory() - 1);
            redisTemplate.opsForValue().set("templateKill_"+TemplateId,templateKill,24,TimeUnit.HOURS);
            //删除锁，可加lua脚本
            String key1 = (String) redisTemplate.opsForValue().get("key");
            if(key1.equals(uuid)) {
                redisTemplate.delete("key");
            }
            return templateKill;
        }else {
            try {
                Thread.sleep(100);
                templateKill = (TemplateKill) redisTemplate.opsForValue().get("templateKill_" + TemplateId);
                if(templateKill!=null && templateKill.getTemplateKillInventory()>0){
                    deleteInventory(TemplateId);
                    return templateKill;
                }else {
                    return null;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
                return null;
            }
        }
    }

    //3. 修改数据库
    public void sendMsg2deleteInventoryNumFromDB(Integer templateKillId){
        rabbitTemplate.convertAndSend("templateKillExchange", "templateKillKey", templateKillId);
    }

    @Override
    public TemplateKill selectById(Integer templateId) {
        return templateKillMapper.selectById(templateId);
    }

    //乐观锁，减数据库内存
    @Transactional
    @RabbitHandler
    @RabbitListener(queues = "templateKillQueue")
    public void deleteInventorySQL(Integer TemplateId, Channel channel, Message message){
        TemplateKill templateKill = templateKillMapper.selectById(TemplateId);
        try {
            if(templateKill==null){
                System.out.println("该商品已不存在，选择其它商品");
            }else {
                QueryWrapper<TemplateKill> wrapper = new QueryWrapper<>();
                wrapper.eq("template_kill_id", TemplateId).eq("beiyong1", templateKill.getBeiyong1());
                wrapper.gt("template_kill_inventory",0);
                templateKill.setBeiyong1(templateKill.getBeiyong1() + 1);
                //减库存
                templateKill.setTemplateKillInventory(templateKill.getTemplateKillInventory() - 1);
                int update = templateKillMapper.update(templateKill, wrapper);
                if (update > 0) {
                    //减库存成功
                    System.out.println("减库存成功，目前剩余数量：" + templateKill.getTemplateKillInventory());
                } else {
                    if(templateKill.getTemplateKillInventory() <= 1){
                        System.out.println("库存已没有");
                    }else {
                        //减库存失败,重新发送消息到消息队列
                        sendMsg2deleteInventoryNumFromDB(TemplateId);
                    }
                }
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
         } catch (IOException e) {
            e.printStackTrace();
            try {
                channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        }
      }





}
